Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue 56: Add pathfinder init #117

Merged
merged 46 commits into from
Mar 8, 2024
Merged

Issue 56: Add pathfinder init #117

merged 46 commits into from
Mar 8, 2024

Conversation

SamuelBrand1
Copy link
Collaborator

@SamuelBrand1 SamuelBrand1 commented Mar 6, 2024

This is a new draft PR aimed at addressing #56 .

The main innovation for this PR occurs here:

function _epi_aware(y_t,
time_steps;
epi_model::AbstractEpiModel,
latent_model::AbstractLatentModel,
observation_model::AbstractObservationModel,
nsamples,
nchains,
pf_ndraws = 50,
pf_nruns = 4,
fixed_parameters = (;),
pos_shift = 1e-6,
executor = Transducers.ThreadedEx(),
adtype = AutoReverseDiff(true),
maxiters = 10,
kwargs...)
gen_mdl = make_epi_aware(missing, time_horizon; epi_model,
latent_model, observation_model, pos_shift) |>
mdl -> fix(mdl, fixed_parameters)
mdl = make_epi_aware(y_t, time_horizon; epi_model,
latent_model, observation_model, pos_shift) |>
mdl -> fix(mdl, fixed_parameters)
safe_mdl = make_epi_aware(y_t, time_horizon, Val(:safe_mode); epi_model,
latent_model, observation_model, pos_shift) |>
mdl -> fix(mdl, fixed_parameters)
mpf = multipathfinder(safe_mdl, max(pf_ndraws, nchains);
nruns = pf_nruns,
executor,
maxiters,
kwargs...)
init_params = collect.(eachrow(mpf.draws_transformed.value[1:nchains, :, 1]))
chn = sample(mdl,
NUTS(; adtype),
MCMCThreads(),
nsamples ÷ nchains,
nchains;
init_params = init_params,
drop_warmup = true)
return chn, (; pathfinder_res = mpf,
inference_mdl = mdl,
generative_mdl = gen_mdl)
end

The aim is to ultimately have _epi_aware as an _internal_method as part of a wider workflow. But for this PR it is getting this functionality available.

The current first pass behaviour is for _epi_aware to take in the information required to act on make_epi_aware; then do multipathfinder and pass the initial parameters to sample (as per this workflow).

Close #56

SamuelBrand1 and others added 30 commits March 1, 2024 18:21
@SamuelBrand1
Copy link
Collaborator Author

I took a step back and rather than trying to implement a full loop of model definition -> init -> NUTS, I've refocussed on having a robust initialisation method.

So now I implement an exported manypathfinder function; this is similar to multipathfinder but aimed at finding a good place in parameter space to initialise NUTS in a situation where early large sample values can cause errors.

manypathfinder does nruns threaded parallel runs of pathfinder and selects the best ELBO estimate run with fails as -Inf.

Copy link
Collaborator

@seabbs seabbs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is much nicer I think. Some safety and quality of life comments + the obvious big merge issue.

EpiAware/docs/src/examples/getting_started.jl Outdated Show resolved Hide resolved
EpiAware/src/inference-methods.jl Show resolved Hide resolved
EpiAware/src/inference-methods.jl Show resolved Hide resolved
EpiAware/src/inference-methods.jl Outdated Show resolved Hide resolved
EpiAware/test/test_inference-methods.jl Show resolved Hide resolved
EpiAware/test/test_inference-methods.jl Show resolved Hide resolved
EpiAware/test/test_inference-methods.jl Outdated Show resolved Hide resolved
EpiAware/test/test_inference-methods.jl Outdated Show resolved Hide resolved
@seabbs
Copy link
Collaborator

seabbs commented Mar 7, 2024

Once this has stabilised and we have taken it out for a spin it would be interesting to float this wrapper to Pathfinder.jl

@codecov-commenter
Copy link

codecov-commenter commented Mar 7, 2024

Codecov Report

Attention: Patch coverage is 97.05882% with 1 lines in your changes are missing coverage. Please review.

Project coverage is 97.61%. Comparing base (6fd57d8) to head (6deb30a).

Files Patch % Lines
EpiAware/src/inference-methods.jl 97.05% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #117      +/-   ##
==========================================
- Coverage   97.76%   97.61%   -0.15%     
==========================================
  Files           6        7       +1     
  Lines         134      168      +34     
==========================================
+ Hits          131      164      +33     
- Misses          3        4       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@SamuelBrand1
Copy link
Collaborator Author

I've increased the testing for manypathfinder:

  • More expected failures.
  • Verbose fail if retries all fail.
  • KS test that the best pathfinder run is a good approximation to a simple normal (if it isn't then thats an obvious problem).

Copy link
Collaborator

@seabbs seabbs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We discussed face to face reordering the inputs to match multipathfinder but think that has yet to happen? Once that is done and we have a new issue for falling back on more functionality from multipathfinder I think this is good to go. It also sounds like we have some confusion about the aim with the docstrings but again perhaps that needs a new issue to discuss..

@SamuelBrand1
Copy link
Collaborator Author

We discussed face to face reordering the inputs to match multipathfinder but think that has yet to happen? Once that is done and we have a new issue for falling back on more functionality from multipathfinder I think this is good to go. It also sounds like we have some confusion about the aim with the docstrings but again perhaps that needs a new issue to discuss..

I've changed the input to match manypathfinder input to multipathfinder, e.g. manypathfinder(mdl, ndraws; kwargs...) -> PathfinderResult is the current signature.

@SamuelBrand1
Copy link
Collaborator Author

After a quick scoping, I don't have immediate plans to use more multipathfinder functionality under the hood anymore.

@seabbs
Copy link
Collaborator

seabbs commented Mar 8, 2024

After a quick scoping, I don't have immediate plans to use more multipathfinder functionality under the hood anymore.

Why

Copy link
Collaborator

@seabbs seabbs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@seabbs seabbs merged commit 4e035ce into main Mar 8, 2024
10 checks passed
@seabbs seabbs deleted the add-pathfinder-init branch March 8, 2024 12:30
@SamuelBrand1
Copy link
Collaborator Author

After a quick scoping, I don't have immediate plans to use more multipathfinder functionality under the hood anymore.

Why

I thought that the try catch pattern in manypathfinder could be replaced by fail_on_nonfinite = false in pathfinder kwargs, but the behaviour of the Distributions.NegativeBinomial distribution constructor chucks an error if we find a NaN during warm-up. manypathfinder is resilient to that fail mode.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

pathfinder based initialisation of Bayesian Inference
3 participants